#include "sensetime_protocol.h"
#include "face.h"
#include "face_common.h"
#include "face_encrypt.h"

static Master_Msg_Cb_fun_t masterMsgcb = NULL; //主控发送任务回调
#define SENSETIME_PROTOCOL_LOG(format, ...) OSAL_LOG(C_CYAN format C_NONE, ##__VA_ARGS__)
/*******************************************************************************/
/******************       人脸模组note信息处理          *************************/
/*******************************************************************************/
/**
  * @brief  处理人脸模组上电准备好note信息
  * @note   开机时模块向主控发送NID_READY
  *
  * 
  */
static void Sensetime_Nid_Ready(void)
{
	SENSETIME_PROTOCOL_LOG("Module power on ready");
	Face_DealParam_stu_t DealParam = {.pinputdata = NULL};
	DealParam.event = FACE_MODULE_POWER_ON_READY_EVENT; //模组上电完成
	Face_Module_Even_Deal(&DealParam);					//人脸模组事件处理
}
/**
  * @brief  处理人脸模组返回的人脸状态信息
  * @note   验证和录入过程中会收到对应信息
  *
  * 
  */
static void Sensetime_Nid_Face_Status(uint8_t *pNoteDataBuf, uint8_t pNoteDataLen)
{
	s_note_data_face *pnoteDataFace = (s_note_data_face *)pNoteDataBuf;
	Face_NoteFaceStatus_stu_t inputdatabuf;
	Face_DealParam_stu_t DealParam = {.pinputdata = NULL};

	//inputdatabuf.status = pnoteDataFace->state;
	memcpy(&inputdatabuf.status, &pnoteDataFace->status, sizeof(Face_NoteFaceStatus_stu_t));
	DealParam.pinputdata = &inputdatabuf;
	DealParam.event = FACE_NID_FACE_STATUS_EVENT; //录入和验证人脸状态信息返回:人脸状态信息返回
	Face_Module_Even_Deal(&DealParam);			  //人脸模组事件处理
}

/**
  * @brief  处理人脸模组OTA状态信息
  * @note   OTA升级过程中会收到对应信息
  *
  * 
  */
static void Ota_DoneSensetime_Nid_Ota_Done(uint8_t *pNoteDataBuf, uint8_t pNoteDataLen)
{
	Face_Ota_Result_stu_t inputdatabuf;
	Face_DealParam_stu_t DealParam = {.pinputdata = NULL};
	DealParam.resultId = OTA_MSGID_NID_OTA_DONE_RESULT;
	switch (pNoteDataBuf[0])
	{
	case 0: //OTA sucess
		inputdatabuf.result = RESULT_SUCCESS_REPORT;
		break;

	case 1: //OTA fail
	default:
		inputdatabuf.result = RESULT_FAIL_REPORT;
		break;
	}
	DealParam.pinputdata = &inputdatabuf;
	DealParam.event = FACE_OTA_FINISH_EVEN; //OTA结束
	Face_Module_Even_Deal(&DealParam);		//人脸模组事件处理
}
/**
  * @brief  处理人脸模组的note信息
  * @note
  *
  * @param  cmd：命令字
  * @param  pData：数据域指针
  * @param  dataLen：数据长度
  * @return 
  */
void Sensetime_Process_Note_Msg(uint8_t cmd, uint8_t *pData, uint8_t dataLen)
{
	switch (cmd)
	{
	case NID_READY:
		Sensetime_Nid_Ready();
		break; //0x00 	模块已准备好
	case NID_FACE_STATE:
		Sensetime_Nid_Face_Status(pData, dataLen);
		break; //返回人脸信息
	case NID_OTA_DONE:
		Ota_DoneSensetime_Nid_Ota_Done(pData, dataLen);
		break;			//OTA升级完毕
	case NID_EYE_STATE: //解锁过程中睁闭眼状态
	default:
		break;
	}
}

/*******************************************************************************/
/******************       人脸模组note信息处理结束      **************************/
/*******************************************************************************/

/*******************************************************************************/
/******************       发送消息给人脸模组处理          ************************/
/*******************************************************************************/
/**
  * @brief  发消息给人脸模组命令包
  *
  * @param  cmd：命令
  * @param  pData：数据域指针
  * @param  dataLen：数据长度
  * @param  cb：入网回调函数
  */
static void Sensetime_SendCmdToNetworkDev(uint8_t cmd, uint8_t *pData, uint16_t dataLen, FaceMessageCallback_fun_t cb, uint32_t timeout)
{
	SensetimeTxCmdMsg_stu_t netData;
	netData.msgID = cmd;
	netData.cb = cb;
	netData.timeout = timeout;
	netData.data_len = dataLen;
	memcpy(netData.dataBuf, pData, dataLen);
	//FaceEncrypt_Encrypt(1, netData.dataBuf, netData.data_len, netData.dataBuf, &netData.data_len);
	//FaceEncrypt_Encrypt( pData, dataLen, netData.dataBuf, &netData.data_len);
	Face_Lock_Tx_Face_Cmd(&netData);
}

/**
  * @brief  人脸验证回调
  * 
  * @param  
  * @note
  *
  * @return 
  */
int32_t Face_Search_Index(uint8_t *userId);
void Sensetime_Verity_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	s_msg_reply_verify_data *pdatabuf = (s_msg_reply_verify_data *)data;
	Face_VerityResult_stu_t resultBuf;
	Face_DealParam_stu_t DealParam = {.pinputdata = NULL};
	switch (result)
	{
	case MR_SUCCESS: //成功
		resultBuf.result = RESULT_SUCCESS_REPORT;
		resultBuf.usernum = pdatabuf->user_name[0]; //用户ID 用user_name数组0下标存储用户id
		resultBuf.user_id_heb = pdatabuf->user_id_heb;
		resultBuf.user_id_leb = pdatabuf->user_id_leb;
		DealParam.event = FACE_VERITY_SUCCESS_FINISHED_EVENT; //人脸验证结束

		/* 比对本地id库 */
		uint16_t face_id = (resultBuf.user_id_heb << 8 ) | resultBuf.user_id_leb;
		if(Face_Search_Index((uint8_t *)&face_id) != resultBuf.usernum)
		{
			/* 删除无用id */
			SENSETIME_PROTOCOL_LOG("can't find id, delete and verify again\r\n");
			Sensetime_Send_Start_DelUser_CMD(face_id);
			/* 重新验证 */
			Sensetime_Send_StartVerity_CMD(1);
			return;
		}
		break;

	case MR_FAILED4_WITHOUTSMILE:
		SENSETIME_PROTOCOL_LOG("no smile\r\n");
		Sensetime_Send_SetAttribute_CMD(0); //取消微笑模式
		resultBuf.result = RESULT_VERIFY_FAIL_REPORT;
		DealParam.event = FACE_VERITY_FAIL_FINISHED_EVENT; //人脸验证结束
		break;
	
	case MR_FAILED4_UNKNOWNUSER:
		SENSETIME_PROTOCOL_LOG("unknown face\r\n");
		resultBuf.result = RESULT_VERIFY_FAIL_REPORT;
		DealParam.event = FACE_VERITY_FAIL_FINISHED_EVENT; //人脸验证结束
		break;

		// case MR_ABORTED:  //录入/解锁算法已终止
	default:
		resultBuf.result = RESULT_FAIL_REPORT;
		DealParam.event = FACE_VERITY_FAIL_FINISHED_EVENT; //人脸验证结束
		break;
	}

	SENSETIME_PROTOCOL_LOG("send startverity result = %#2x,usernum = %#2x,id_heb = %#2x,id_leb = %#2x", result, resultBuf.usernum, resultBuf.user_id_heb, resultBuf.user_id_leb);
	DealParam.pinputdata = &resultBuf;

	Face_Module_Even_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  发送启动验证的消息给人脸模组
  * 
  * @param  time ：超时时间等于time*(FACE_VERITIFYING_TIMEOUT-FACE_MODULE_DEAL_TIMEOUT_SMALL)
  * @note
  *
  * @return 
  */
void Sensetime_Send_StartVerity_CMD(uint8_t time)
{
	uint8_t len = sizeof(s_msg_verify_data);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_verify_data *pdatabuf = (s_msg_verify_data *)databuf;
	FaceMessageCallback_fun_t cb = Sensetime_Verity_Callback;
	pdatabuf->timeout = time * (FACE_VERITIFYING_TIMEOUT - FACE_MODULE_DEAL_TIMEOUT_SMALL) / FACE_ONE_SEC_OF_MSEC;
	Sensetime_SendCmdToNetworkDev(MID_VERIFY, databuf, len, cb, time * FACE_VERITIFYING_TIMEOUT);
}

/**
  * @brief  发送特性设置给人脸模组
  * 
  * @note
  * @param flag
  * @return 
  */
void Sensetime_Send_SetAttribute_CMD(uint8_t flag)
{
	uint8_t len = sizeof(s_msg_attribute_data);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_attribute_data *pdatabuf = (s_msg_attribute_data *)databuf;
	FaceMessageCallback_fun_t cb = NULL;
	pdatabuf->flag = flag;
	Sensetime_SendCmdToNetworkDev(MID_ENABLE_ATTRIBUTE, databuf, len, cb, FACE_NORMAL_TIMEOUT);
}

/**
  * @brief  人脸模组掉电操作回调
  * 
  * @param  
  * @note
  *
  * @return 
  */
void Sensetime_PowerDowm_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	Face_DealParam_stu_t DealParam = {
		.pinputdata = NULL,
	};

	if (result == MR_SUCCESS) //成功
	{
		DealParam.event = FACE_SLEEPING_ALLOW_EVENT;
	}
	else if (ACK_RES_TIMEOUT == result)
	{
		DealParam.event = FACE_TIMEOUT_ENENT;
	}
	else
	{
		DealParam.event = FACE_SLEEPING_DISALLOW_EVENT;
	}

	SENSETIME_PROTOCOL_LOG("send powerDown result = %#2x", result);
	Face_Module_Even_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  发送准备掉电的消息给人脸模组
  * 
  * @param  
  * @note
  *
  */
void Sensetime_Send_PowerDowm_CMD(void)
{
	FaceMessageCallback_fun_t cb = Sensetime_PowerDowm_Callback;
	Sensetime_SendCmdToNetworkDev(MID_POWERDOWN, NULL, 0, cb, FACE_POWERDOWN_TIMEOUT);
}

/**
  * @brief  人脸模组终止当前操作回调
  * 
  * @param  
  * @note
  *
  * @return 
  */
void Sensetime_Reset_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	Face_DealParam_stu_t DealParam = {.pinputdata = NULL};
	switch (result)
	{
	case MR_SUCCESS:							  //成功
		DealParam.event = FACE_IDLE_SUCCESS_EVEN; //成功进入IDLE模式
		break;

	default:
		DealParam.event = FACE_TIMEOUT_ENENT; //当做超时
		break;
	}

	Face_Module_Even_Deal(&DealParam); //人脸模组事件处理
}
/**
  * @brief  发送终止当前操作指令（验证、注册）
  * 
  * @param  
  * @note
  *
  */
void Sensetime_Send_Reset_CMD(void)
{
	uint32_t timeout = FACE_IDLE_TIMEOUT - FACE_MODULE_DEAL_TIMEOUT_SMALL;
	FaceMessageCallback_fun_t cb = Sensetime_Reset_Callback;
	Sensetime_SendCmdToNetworkDev(MID_RESET, NULL, 0, cb, timeout);
}

/**
  * @brief  人脸注册回调
  * 
  * @param  
  * @note
  *
  * @return 
  */
static void Sensetime_Enroll_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	s_msg_reply_enroll_data *pdatabuf = (s_msg_reply_enroll_data *)data;
	Face_EnrollResult_stu_t resultBuf;
	Face_DealParam_stu_t DealParam = {.pinputdata = NULL};

	switch (result)
	{
	case MR_SUCCESS:
#if defined(FACE_ENROLL_SINGLE)						  //单帧录入
		DealParam.event = FACE_ENROLL_FINISHED_EVENT; //人脸录入结束：录入结束
		resultBuf.result = RESULT_SUCCESS_REPORT;	  //录入成功
		resultBuf.user_id = (pdatabuf->user_id_heb << 8 ) | pdatabuf->user_id_leb;
#else
		if (pdatabuf->face_direction == FACE_DIRECTION_ALL) //全部人脸录入完成
		{
			DealParam.event = FACE_ENROLL_FINISHED_EVENT; //人脸录入结束：录入结束
			resultBuf.result = RESULT_SUCCESS_REPORT;	  //录入成功
			resultBuf.enrolledFaceDir = pdatabuf->face_direction;
			resultBuf.user_id = (pdatabuf->user_id_heb << 8 ) | pdatabuf->user_id_leb;
		}
		else
		{
			DealParam.event = FACE_ENROLL_ENROLL_NEXT_DIR_EVENT; //人脸录入下一方向人脸 ：录入下一方向人脸
			resultBuf.result = RESULT_CONTINULE;				 //继续下一步
			resultBuf.enrolledFaceDir = pdatabuf->face_direction;
		}
#endif
		break;

	case MR_FAILED4_FACEENROLLED:					  //人脸已录入
		DealParam.event = FACE_ENROLL_FINISHED_EVENT; //人脸录入结束：录入结束
		resultBuf.result = RESULT_FACE_ENROLLED;
		break;

	case MR_FAILED4_MAXUSER: //录入超过最大用户数量
		SENSETIME_PROTOCOL_LOG("face enroll max user");
	default:
		DealParam.event = FACE_ENROLL_FINISHED_EVENT; //人脸录入结束：录入结束
		resultBuf.result = RESULT_FAIL_REPORT;		  //失败
		break;
	}
	SENSETIME_PROTOCOL_LOG("send enrolling result = %#2x,num_L=%#2x,num_H=%#2x,dir=%#2x", result, pdatabuf->user_id_leb, pdatabuf->user_id_heb, pdatabuf->face_direction);
	DealParam.pinputdata = &resultBuf;
	Face_Module_Even_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  发送启动注册的消息给人脸模组
  * 
  * @param  num:人脸编号
  * @param  direction：字符串描述的人脸方向："right" "left" "up" "dowm" "middle"
  * 
  * @note
  *
  */
void Sensetime_Send_StartEnroll_CMD(uint8_t num, s_face_dir direction)
{
	uint8_t len = sizeof(s_msg_enroll_data);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_enroll_data *pdatabuf = (s_msg_enroll_data *)databuf;

	pdatabuf->face_direction = direction;
	pdatabuf->user_name[0] = num;
	pdatabuf->admin = 0;
	FaceMessageCallback_fun_t cb = Sensetime_Enroll_Callback;
	pdatabuf->timeout = (FACE_ENROLLING_TIMEOUT - FACE_MODULE_DEAL_TIMEOUT_SMALL) / FACE_ONE_SEC_OF_MSEC;
#if defined(FACE_ENROLL_SINGLE) //单帧录入
	Sensetime_SendCmdToNetworkDev(MID_ENROLL_SINGLE, databuf, len, cb, FACE_ENROLLING_TIMEOUT);
#else
	Sensetime_SendCmdToNetworkDev(MID_ENROLL, databuf, len, cb, FACE_ENROLLING_TIMEOUT);
#endif
}

/**
  * @brief  发送清除录入记录给模组
  * 
  * 
  * @note
  *
  */
void Sensetime_Send_FaceReset_CMD(void)
{
	Sensetime_SendCmdToNetworkDev(MID_FACERESET, NULL, 0, NULL, FACE_FACE_RESET_TIMEOUT);
}

/**
  * @brief  人脸删除单个用户回调
  * 
  * @param  
  * @note
  *
  * @return 
  */
static void Sensetime_DelUser_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	Face_DeleteResult_stu_t resultBuf;
	Face_DealParam_stu_t DealParam = {.pinputdata = NULL};

	// resultBuf.mode = FACE_MODULE_ENROLLING_MODE;
	switch (result)
	{
	case MR_SUCCESS:
		DealParam.event = FACE_DELETE_FINISH_EVENT; //删除完成
		resultBuf.result = RESULT_SUCCESS_REPORT;	//删除成功
		break;

	default:
		DealParam.event = FACE_DELETE_FINISH_EVENT; //删除完成
		resultBuf.result = RESULT_FAIL_REPORT;		//失败
		break;
	}
	SENSETIME_PROTOCOL_LOG("send deleting user result = %#2x", result);
	DealParam.pinputdata = &resultBuf;
	Face_Module_Even_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  发送删除单个人脸的消息给人脸模组
  * 
  * @param  user_id 存储于人脸模组的用户ID
  * 
  * @note
  *
  * @return 
  */
void Sensetime_Send_Start_DelUser_CMD(uint16_t user_id)
{
	uint8_t len = sizeof(s_msg_deluser_data);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_deluser_data *pdatabuf = (s_msg_deluser_data *)databuf;

	pdatabuf->user_id_heb = (user_id >> 8) & 0xFF;
	pdatabuf->user_id_leb = user_id & 0xFF;
	FaceMessageCallback_fun_t cb = Sensetime_DelUser_Callback;
	Sensetime_SendCmdToNetworkDev(MID_DELUSER, databuf, len, cb, FACE_DELETING_TIMEOUT);
}

/**
  * @brief  人脸删除全部用户回调
  * 
  * @param  
  * @note
  *
  * @return 
  */
static void Sensetime_DelAll_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	Face_DeleteResult_stu_t resultBuf;
	Face_DealParam_stu_t DealParam = {.pinputdata = NULL};

	//resultBuf.mode = FACE_MODULE_ENROLLING_MODE;
	switch (result)
	{
	case MR_SUCCESS:
		DealParam.event = FACE_DELETE_FINISH_EVENT; //删除完成
		resultBuf.result = RESULT_SUCCESS_REPORT;	//删除成功
		break;
	default:
		DealParam.event = FACE_DELETE_FINISH_EVENT; //删除完成
		resultBuf.result = RESULT_FAIL_REPORT;		//失败
		break;
	}
	SENSETIME_PROTOCOL_LOG("send deleting all result = %#2x", result);
	DealParam.pinputdata = &resultBuf;
	Face_Module_Even_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  发送删除全部人脸的消息给人脸模组
  * 
  * 
  * @note
  *
  * @return 
  */
void Sensetime_Send_Start_DelAll_CMD(void)
{
	FaceMessageCallback_fun_t cb = Sensetime_DelAll_Callback;
	Sensetime_SendCmdToNetworkDev(MID_DELALL, NULL, 0, cb, FACE_DELETING_TIMEOUT);
}

/**
  * @brief  人脸启动升级回调
  * 
  * @param  
  * @note
  *
  * @return 
  */
static void Sensetime_StartOta_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	Face_StartOta_Result_stu_t *presultSuccessBuf = (Face_StartOta_Result_stu_t *)databuf;
	Face_Ota_Result_stu_t *presultFailBuf = (Face_Ota_Result_stu_t *)databuf;
	Face_DealParam_stu_t DealParam = {.pinputdata = databuf};
	DealParam.resultId = OTA_MSGID_SEND_START_OTA_RESULT; //发送启动OTA结果
	switch (result)
	{
	case MR_SUCCESS: //成功
		presultSuccessBuf->result = RESULT_SUCCESS_REPORT;
		DealParam.event = FACE_OTA_PREPAREING_EVEN; //OTA 前期准备
		break;

	default:
		presultFailBuf->result = RESULT_FAIL_REPORT;
		DealParam.event = FACE_OTA_FINISH_EVEN; //OTA结束
		break;
	}

	DealParam.pinputdata = databuf;
	Face_Module_Even_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  发送启动升级的消息给人脸模组
  * 
  * @param  
  * @note
  *
  */
void Sensetime_Send_StartOta_CMD(void)
{
	uint8_t len = sizeof(s_msg_startota_data);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_startota_data *pdatabuf = (s_msg_startota_data *)databuf;
	FaceMessageCallback_fun_t cb = NULL;
	//pdatabuf->ota_type = type;
	pdatabuf->v_primary = 0x00;
	pdatabuf->v_secondary = 0x00;
	pdatabuf->v_revision = 0x00;
	cb = Sensetime_StartOta_Callback;

	Sensetime_SendCmdToNetworkDev(MID_START_OTA, databuf, len, cb, FACE_MID_START_OTA_TIMEOUT);
}

/**
  * @brief  人脸获取模块OTA状态回调
  * 
  * @param  
  * @note
  *
  * @return 返回命令处理结果
  */
static void Sensetime_GetOtaStatus_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_reply_getOtaStatus_data *pdatabuf = (s_msg_reply_getOtaStatus_data *)data;
	Face_GetOtaStatus_Result_stu_t *presultSuccessBuf = (Face_GetOtaStatus_Result_stu_t *)databuf;
	Face_Ota_Result_stu_t *presultFailBuf = (Face_Ota_Result_stu_t *)databuf;
	Face_DealParam_stu_t DealParam = {.pinputdata = &databuf};
	DealParam.resultId = OTA_MSGID_SEND_GET_OTA_STATUS_RESULT; //发送获取OTA状态结果
	switch (result)
	{
	case MR_SUCCESS: //成功
		presultSuccessBuf->result = RESULT_SUCCESS_REPORT;
		presultSuccessBuf->otaStatus = (pdatabuf->ota_status == 0x04) ? SET : RESET;
		presultSuccessBuf->nextOtaPid = pdatabuf->next_pid_e;
		DealParam.event = FACE_OTA_PREPAREING_EVEN; //OTA 前期准备
		break;

	default:
		presultFailBuf->result = RESULT_FAIL_REPORT;
		DealParam.event = FACE_OTA_FINISH_EVEN; //OTA结束
		break;
	}
	DealParam.pinputdata = &databuf;

	Face_Module_Even_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  发送获取模块OTA状态消息给人脸模组
  * 
  * @param  
  * @note
  *
  */
void Sensetime_Send_GetOtaStatus_CMD(void)
{
	FaceMessageCallback_fun_t cb = Sensetime_GetOtaStatus_Callback;
	Sensetime_SendCmdToNetworkDev(MID_GET_OTA_STATUS, NULL, 0, cb, FACE_MID_GET_OTA_STATUS_TIMEOUT);
}

/**
  * @brief  发送结束升级的消息给人脸模组回调
  * 
  * @param  
  * @note
  *
  * @return 
  */
static void Sensetime_StopOta_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	//Face_StartOta_Result_stu_t *presultSuccessBuf = (Face_StartOta_Result_stu_t *)databuf;
	Face_Ota_Result_stu_t *presultFailBuf = (Face_Ota_Result_stu_t *)databuf;
	Face_DealParam_stu_t DealParam = {.pinputdata = databuf};
	// DealParam.resultId = OTA_MSGID_SEND_START_OTA_RESULT;      //发送启动OTA结果
	// switch(result)
	// {
	//   case MR_SUCCESS:    //成功
	//     presultSuccessBuf->result = RESULT_SUCCESS_REPORT;
	//     DealParam.event = FACE_OTA_PREPAREING_EVEN;   //OTA 前期准备
	//     break;

	//   default:
	//     presultFailBuf->result = RESULT_FAIL_REPORT;
	//     DealParam.event = FACE_OTA_FINISH_EVEN;         //OTA结束
	//     break;
	// }
	presultFailBuf->result = RESULT_FAIL_REPORT;
	DealParam.event = FACE_OTA_FINISH_EVEN; //OTA结束
	DealParam.pinputdata = databuf;
	Face_Module_Even_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  发送结束升级的消息给人脸模组
  * 
  * @param  
  * @note
  *
  */
void Sensetime_Send_StopOta_CMD(void)
{
	FaceMessageCallback_fun_t cb = Sensetime_StopOta_Callback;
	Sensetime_SendCmdToNetworkDev(MID_STOP_OTA, NULL, 0, cb, FACE_MID_START_OTA_TIMEOUT);
}

/**
  * @brief  人脸设置debug模式回调
  * 
  * @param  
  * @note
  *
  * @return 
  */
static void Sensetime_SetDebugMode_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	Face_SetWorkMode_Result_stu_t *presultBuf = (Face_SetWorkMode_Result_stu_t *)databuf;
	Face_DealParam_stu_t DealParam = {.pinputdata = databuf};
	DealParam.resultId = FACE_TASK_MSGID_MAX; //无效值
	switch (result)
	{
	case MR_SUCCESS: //成功
		presultBuf->result = RESULT_SUCCESS_REPORT;
		break;

	default:
		presultBuf->result = RESULT_FAIL_REPORT;
		break;
	}
	DealParam.event = FACE_SET_FINISH_EVENT; //设置结束
	Face_Module_Even_Deal(&DealParam);		 //人脸模组事件处理
}
/**
  * @brief  发送设置演示模式消息给人脸模组
  * 
  * @param  mode :0x01： demo       0x00：正常工作模式
  * @note
  *
  */
void Sensetime_Send_SetDemoMode_CMD(uint8_t mode)
{
	uint8_t len = sizeof(s_msg_set_debugmode);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_set_debugmode *pdatabuf = (s_msg_set_debugmode *)databuf;

	pdatabuf->mode = mode; //设置工作模式
	FaceMessageCallback_fun_t cb = Sensetime_SetDebugMode_Callback;
	Sensetime_SendCmdToNetworkDev(MID_DEMOMODE, databuf, len, cb, FACE_NORMAL_TIMEOUT);
}

static ErrorStatus _get_version(uint8_t *pData, uint8_t dataLen, uint8_t *pVersion, uint8_t *pModel)
{
	ErrorStatus ret = ERROR;
	uint8_t i = 0, j = 0;
	uint8_t head = 0;
	uint8_t len_buf = 0;

	/* 字符截取 */
	for (i = 0; i < dataLen; i++)
	{
		if (!(pData[i] >= 0x20 && pData[i] <= 0x7E)) //可显字符
		{
			break;
		}
	}
	len_buf = i;
	if (len_buf >= dataLen)
	{
		return ERROR;
	}

	/* 解析型号 */
	for (i = 0; i < len_buf; i++)
	{
		if (pData[i] == '_')
		{
			break;
		}
	}
	if (i <= FACE_MODEL_LEN)
	{
		memcpy(pModel, pData, i);
	}

	/* 解析版本号 */
	for (i = 0; i < len_buf; i++)
	{
		if (pData[i] >= 'A' && pData[i] <= 'Z') //最后一个大写字母后面为版本号
		{
			memset(pVersion, 0, j);
			head = 1;
			j = 0;
		}	
		if (head)
		{
			pVersion[j++] = pData[i];
		}
	}

	if (j && j < FACE_VERSION_LEN)
	{
		/* 校验版本号格式 */
		for (i = 1; i < j; i++)
		{
			if (!((pVersion[i] >= '0' && pVersion[i] <= '9') || pVersion[i] == '.'))
			{
				memset(pVersion, 0, FACE_VERSION_LEN);
				return ERROR;
			}
		}
		ret = SUCCESS;
	}
	return ret;
}

/**
  * @brief  发送获取软件版本消息给人脸模组回调
  * 
  * @param  
  * @note
  *
  * @return 
  */
extern ErrorStatus Face_WriteFaceVersion(uint8_t *pData);
extern ErrorStatus Face_Write_Model(uint8_t *pData);
static void Sensetime_Get_Version_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	Face_GetVersion_Result_stu_t *presultBuf = (Face_GetVersion_Result_stu_t *)databuf;
	s_msg_reply_version_data *pdatabuf = (s_msg_reply_version_data *)data;
	Face_DealParam_stu_t DealParam = {.pinputdata = databuf};
	uint8_t version[FACE_VERSION_LEN] = {0};
	uint8_t model[FACE_MODEL_LEN] = {0};
	DealParam.resultId = FACE_TASK_MSGID_MAX; //无效值
	switch (result)
	{
	case MR_SUCCESS: //成功
		if (SUCCESS == _get_version(pdatabuf->version_info, VERSION_INFO_BUFFER_SIZE, version, model))
		{
			presultBuf->result = RESULT_SUCCESS_REPORT;
			Face_WriteFaceVersion(version);
			Face_Write_Model(model);
		}

		break;

	default:
		presultBuf->result = RESULT_FAIL_REPORT;
		break;
	}
	if (masterMsgcb != NULL)
	{
		masterMsgcb(presultBuf->result, version, FACE_VERSION_LEN);
		masterMsgcb = NULL;
	}

	DealParam.event = FACE_SET_FINISH_EVENT; //设置结束
	Face_Module_Even_Deal(&DealParam);		 //人脸模组事件处理
}
/**
  * @brief  发送获取软件版本消息给人脸模组
  * 
  * @param  mode :0x01： debug       0x00：正常工作模式
  * @note
  *
  */
void Sensetime_Send_Get_Version_CMD(Master_Msg_Cb_fun_t callback)
{
	uint8_t len = 1;
	uint8_t databuf[2] ={0};
	databuf[0] = 0X4B;
	FaceMessageCallback_fun_t cb = Sensetime_Get_Version_Callback;
	Sensetime_SendCmdToNetworkDev(MID_GET_VERSION, databuf, len, cb, FACE_NORMAL_TIMEOUT);
}

/**
  * @brief  人脸设置加密模式回调
  * 
  * @param  
  * @note
  *
  * @return 
  */
static void Sensetime_InitEncryption_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	Face_Encryption_Result_stu_t *presultBuf = (Face_Encryption_Result_stu_t *)databuf;
	s_msg_reply_init_encryption_data *pdata = (s_msg_reply_init_encryption_data *)data;
	Face_DealParam_stu_t DealParam = {.pinputdata = databuf};
	switch (result)
	{
	case MR_SUCCESS:								//成功
		presultBuf->result = RESULT_SUCCESS_REPORT; //成功
		DealParam.event = FACE_POWER_ON_ENCRYPT_FINISH_EVEN;
		memcpy(presultBuf->faceSN, pdata->device_id, len);
		// DealParam.event = Sensetime_FaceSn_Comprison(presultBuf->faceSN, s_msg_reply_init_encryption_data);
		break;

	default:
		presultBuf->result = RESULT_FAIL_REPORT; //失败
		DealParam.event = FACE_POWER_ON_ENCRYPT_FINISH_EVEN;
		break;
	}
	Face_Module_Even_Deal(&DealParam); //人脸模组事件处理
}
/**
  * @brief  发送设置加密模式给人脸模组
  * 
  * @param  seed :随机序列(4个字节)
  *         time :当前时间戳(4个字节)
  * @note
  *
  */
void Sensetime_Send_InitEncryption_CMD(uint8_t *seed, uint8_t seedlen, uint8_t *time, uint8_t timelen)
{
	uint8_t len = sizeof(s_msg_init_encryption_data);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_init_encryption_data *pdatabuf = (s_msg_init_encryption_data *)databuf;
	memcpy(pdatabuf->seed, seed, 4);
	memcpy(pdatabuf->crttime, time, 4);
	pdatabuf->mode = ST_ENCMODE_AES; //AES加密模式
	FaceMessageCallback_fun_t cb = Sensetime_InitEncryption_Callback;
	Sensetime_SendCmdToNetworkDev(MID_INIT_ENCRYPTION, databuf, len, cb, FACE_NORMAL_TIMEOUT);
}

/**
  * @brief  人脸设置加密key逻辑回调
  * 
  * @param  
  * @note
  *
  * @return 
  */
static void Sensetime_DebugEncrytionKeyNum_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	Face_EncrytionKeyNum_Result_stu_t *presultBuf = (Face_EncrytionKeyNum_Result_stu_t *)databuf;
	Face_DealParam_stu_t DealParam = {.pinputdata = databuf};
	DealParam.resultId = FACE_TASK_MSGID_MAX; //无效值

	switch (result)
	{
	case MR_SUCCESS: //成功
		DealParam.event = FACE_POWER_ON_INIT_ENCRYPT_EVEN;
		presultBuf->result = RESULT_SUCCESS_REPORT;
		break;

	default:
		DealParam.event = FACE_POWER_ON_ENCRYPT_FINISH_EVEN;
		presultBuf->result = RESULT_FAIL_REPORT;
		break;
	}
	Face_Module_Even_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  发送加密key的逻辑人脸模组
  * 
  * @param  data :密钥的选择逻辑（16个字节）
  * @note
  *
  */
void Sensetime_Send_DebugEncrytionKeyNum_Cmd(uint8_t *data, uint8_t datalen)
{
	uint8_t len = sizeof(s_msg_enc_key_number_data);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_enc_key_number_data *pdatabuf = (s_msg_enc_key_number_data *)databuf;
	memcpy(pdatabuf->enc_key_number, data, datalen);

	FaceMessageCallback_fun_t cb = Sensetime_DebugEncrytionKeyNum_Callback;
	Sensetime_SendCmdToNetworkDev(MID_SET_DEBUG_ENC_KEY, databuf, len, cb, FACE_NORMAL_TIMEOUT);
}

/**
  * @brief  人脸设置量产加密秘钥序列回调
  * 
  * @param  
  * @note
  *
  * @return 
  */
static void Sensetime_ReleaseEncrytionKeyNum_Callback(uint8_t result, uint8_t *data, uint8_t len)
{
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	Face_EncrytionKeyNum_Result_stu_t *presultBuf = (Face_EncrytionKeyNum_Result_stu_t *)databuf;
	Face_DealParam_stu_t DealParam = {.pinputdata = databuf};
	DealParam.resultId = SET_MSGID_SET_RELEASE_ENC; //设定量产加密秘钥序列

	switch (result)
	{
	case MR_SUCCESS: //成功
		presultBuf->result = RESULT_SUCCESS_REPORT;
		break;

	case MR_REJECTED:						   //模块拒接该命令
		presultBuf->result = RESULT_ENCRYPTED; //已加密
		break;

	default:
		presultBuf->result = RESULT_FAIL_REPORT;
		break;
	}
	DealParam.event = FACE_SET_FINISH_EVENT;
	Face_Module_Even_Deal(&DealParam); //人脸模组事件处理
}

/**
  * @brief  人脸设置量产加密秘钥序列
  * 
  * @param  data :密钥的选择逻辑（16个字节）
  * @note
  *
  */
void Sensetime_Send_ReleaseEncrytionKeyNum_Cmd(uint8_t *data, uint8_t datalen)
{
	uint8_t len = sizeof(s_msg_enc_key_number_data);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_enc_key_number_data *pdatabuf = (s_msg_enc_key_number_data *)databuf;
	memcpy(pdatabuf->enc_key_number, data, datalen);

	FaceMessageCallback_fun_t cb = Sensetime_ReleaseEncrytionKeyNum_Callback;
	Sensetime_SendCmdToNetworkDev(MID_SET_RELEASE_ENC_KEY, databuf, len, cb, FACE_NORMAL_TIMEOUT);
}

/**
  * @brief  人脸设置算法安全等级
  * 
  * @param  data :
  * @note
  *
  */
void Sensetime_Send_SetThresholdLevel_Cmd(uint8_t verify_threshold_level, uint8_t liveness_threshold_level)
{
	uint8_t len = sizeof(s_msg_algo_threshold_level);
	uint8_t databuf[SENSE_TIME_CMD_DATA_LEN] = {0};
	s_msg_algo_threshold_level *pdatabuf = (s_msg_algo_threshold_level *)databuf;
	pdatabuf->verify_threshold_level = verify_threshold_level;
	pdatabuf->liveness_threshold_level = liveness_threshold_level;

	Sensetime_SendCmdToNetworkDev(MID_SET_THRESHOLD_LEVEL, databuf, len, 0, FACE_NORMAL_TIMEOUT);
}
